﻿using System;
using System.Collections.Generic;
using System.Linq;
using ITTestingSystem.BusinessLogic.DataServices.Abstract;

namespace ITTestingSystem.BusinessLogic.DataServices.Concrete
{
    /// <summary>
    /// 
    /// </summary>
    /// 
    /// <typeparam name="T">
    /// 
    /// </typeparam>
    /// 
    public class BaseService<T> : IBaseService<T>, IDisposable where T : class
    {
        #region IBaseService implementation

        /// <summary>
        /// 
        /// </summary>
        /// 
        protected readonly IRepositoryForEntity<T> Repository;

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="repository">
        /// 
        /// </param>
        /// 
        public BaseService(IRepositoryForEntity<T> repository)
        {
            Repository = repository;
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="item">
        /// 
        /// </param>
        /// 
        void IBaseService<T>.Add(T item)
        {
            if (IsNull(item))
            {
                throw new ArgumentNullException();
            }

            Repository.Add(item);
            Repository.Save();
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <returns>
        /// 
        /// </returns>
        /// 
        IEnumerable<T> IBaseService<T>.GetAll()
        {
            // Обов'язково треба агрегуючу функцію
            // щоб запит вже на цьому етапі виконувався

            return Repository.GetAll().ToList();
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="id">
        /// 
        /// </param>
        /// 
        /// <returns>
        /// 
        /// </returns>
        /// 
        T IBaseService<T>.GetById(int id)
        {
            return Repository.GetById(id);
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="item">
        /// 
        /// </param>
        /// 
        void IBaseService<T>.Update(T item)
        {
            if (IsNull(item))
            {
                throw new ArgumentNullException();
            }

            Repository.Update(item);
            Repository.Save();
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="id">
        /// 
        /// </param>
        /// 
        void IBaseService<T>.DeleteById(int id)
        {
            Repository.DeleteById(id);
            Repository.Save();
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="item">
        /// 
        /// </param>
        /// 
        void IBaseService<T>.Delete(T item)
        {
            if (IsNull(item))
            {
                throw new ArgumentNullException();
            }

            Repository.Delete(item);
            Repository.Save();
        }

        #endregion

        private static bool IsNull(object parameter)
        {
            return parameter == null;
        }

        #region Реалізація IDisposible

        /// <summary>
        /// 
        /// </summary>
        /// 
        private bool _disposed;

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="disposing">
        /// 
        /// </param>
        /// 
        protected void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing)
            {
                if (Repository is IDisposable)
                {
                    (Repository as IDisposable).Dispose();
                }
            }

            _disposed = true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
